// https://github.com/uxitten/polyfill/blob/master/string.polyfill.js
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat
if (!String.prototype.padEnd) {
    String.prototype.padEnd = function padEnd(targetLength,padString) {
        targetLength = targetLength>>0; //floor if number or convert non-number to 0;
        padString = String(padString || ' ');
        if (this.length > targetLength) {
            return String(this);
        }
        else {
            targetLength = targetLength-this.length;
            if (targetLength > padString.length) {
                padString += padString.repeat(targetLength/padString.length); //append to original to ensure we are longer than needed
            }
            return String(this) + padString.slice(0,targetLength);
        }
    };
}

import { Base64 } from 'js-base64';

const reader = new FileReader();

function stringSplice(str, start, delCount, newSubStr) {
    return str.slice(0, start) + newSubStr + str.slice(start + Math.abs(delCount));
};

function getFileInfo(file) {
    var ret = {};
    for (var key in file) {
        if (key != "slice") {
            ret[key] = file[key]
        }
    }
    return ret;
}

 function readStrFromBlob(blob) {
    return new Promise(function (resolve, reject) {        
        // This fires after the blob has been read/loaded.
        reader.addEventListener('loadend', (e) => {
          resolve(reader.result);
        });
        
        // Start reading the blob as text.
        reader.readAsText(blob);        
    })
}

export function decodeFileBlob(file) {
    return new Promise(function (resolve, reject) {
        readStrFromBlob(file.slice(0, 10)).then(function (text) {
            const metalength = parseInt(text.replace(/\*/g, ""));              
            readStrFromBlob(file.slice(20, metalength + 20)).then(function (metastr) {
                resolve({
                    meta: JSON.parse(Base64.decode(metastr)), 
                    file: file.slice(metalength + 20),
                    time: new Date()
                });  
            })
        }).catch(function (e) {
            reject(e);
        }) 
    })
}

export function encodeFileBlob(file, append) {
    var info = getFileInfo(file);    
    info = Object.assign(info, append);
    var c = Base64.encode(JSON.stringify(info));
    var s = new Blob([c]);
    var meta = s.size + "";
    if (meta.length < 10) {
        meta = meta.padEnd(10, "*")
    }
    c = stringSplice(c, 0, 0, meta);
    var r = new Blob([meta, c, file]);
    return r;
}

// const FileChunkSize  = 64 * 1024; // bytes

const FileChunkSize  = 1024 * 1024; // bytes

function generateFileChunk(offset, chunkSize, file) {
    return file.slice(offset, offset + chunkSize);
}

function parseFileToFileChunk(file) {
    var offset = 0;
    var fileSize = file.size;
    var chunk = [];

    while (offset <= fileSize) {
        chunk.push(generateFileChunk(offset, FileChunkSize, file));
        offset = offset + FileChunkSize;   
    }

    console.log('------------------------------------');
    console.log(chunk);
    console.log('------------------------------------');

    return chunk;
}

export function encode(info, blob, append, file) {
    info = Object.assign(info, append);
    var c = Base64.encode(JSON.stringify(info));
    var s = new Blob([c]);
    var meta = s.size + "";
    if (meta.length < 10) {
        meta = meta.padEnd(10, "*")
    }
    c = stringSplice(c, 0, 0, meta);
    var r = new Blob([meta, c, blob]);
    return r;
}

export function encodeFileBlobChunk(file, append) {
    var info = getFileInfo(file);    
    var blobs = parseFileToFileChunk(file);
    info.chunkInfo = {};
    info.chunkInfo.size = blobs.length;
    
    blobs = blobs.map(function (blob) {
        return encode(info, blob, append);    
    })
    return blobs;
}